package fiado.dao.memory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import fiado.bean.Produto;
import fiado.exception.DaoException;


public class ProdutoDAO {

	public static final List<Produto> tabela = Collections.synchronizedList(new ArrayList<Produto>());

	public static int nextValue = 10;
	
	static {
		try {
			Produto p = criarProduto(1, "Bauru", "10/10/2011", 2.5);
			ProdutoDAO.tabela.add(p);
			p = criarProduto(2, "Coxinha", "10/10/2011", 1.5);
			ProdutoDAO.tabela.add(p);
			p = criarProduto(3, "Pastel", "10/10/2011", 1.0);
			ProdutoDAO.tabela.add(p);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

	private static Produto criarProduto(
			int id, 
			String descricao, 
			String dataCriacao, 
			double valor) throws ParseException {
		Produto p = new Produto();
		p.setId(id);
		p.setDescricao(descricao);
		p.setValor(valor);
		if (dataCriacao != null) {
			p.setDataCriacao(new SimpleDateFormat("dd/MM/yyyy").parse(dataCriacao));
		}
		return p;
	}
	
	private static List<Produto> copy(List<Produto> lista) {
		List<Produto> listaCopia = new ArrayList<Produto>();
		for (Produto p : lista) {
			listaCopia.add(copy(p));
		}
		return listaCopia;
	}
	
	private static Produto copy(Produto p) {
		Produto copy = new Produto();
		copy.setId(p.getId());
		copy.setDescricao(p.getDescricao());
		copy.setValor(p.getValor());
		copy.setDataCriacao(p.getDataCriacao());
		return copy;
	}	
	private int getProximoValorSequence() throws DaoException {
		return nextValue++;
	}
	
	/**
	 * Este metodo retorna uma lista com todos os objetos Produto armazenados
	 * @return
	 * @throws DaoException 
	 */
	public List<Produto> buscarTodos() throws DaoException {
		return copy(ProdutoDAO.tabela);
	}

	/**
	 * Este metodo retorna uma lista com todos os objetos Produto armazenados
	 * que possuam <nome> no campo prenome ou no campo sobrenome
	 * @return
	 * @throws DaoException 
	 */
	public List<Produto> buscarPorDescricao(String descricao) throws DaoException {
		descricao = ".*" + descricao + ".*";
		List<Produto> lista = new ArrayList<Produto>();

		for (Produto p : ProdutoDAO.tabela) {
			if (p.getDescricao().matches(descricao)) {
				lista.add(copy(p));
			}
		}

		return lista;
	}
	
	/**
	 * Este metodo retorna o objeto Produto de acordo com o id
	 * @return
	 * @throws DaoException 
	 */
	public Produto buscarPorId(int idProduto) throws DaoException {
		for (Produto p : ProdutoDAO.tabela) {
			if (p.getId() == idProduto) {
				return copy(p);
			}
		}
		return null;
	}
	
	/**
	 * Este metodo apaga o objeto Produto de acordo com o id
	 * @throws DaoException 
	 */
	public void apagar(int idProduto) throws DaoException {
		Iterator<Produto> it = ProdutoDAO.tabela.iterator();
		while (it.hasNext()) {
			Produto p = it.next();
			if (p.getId() == idProduto) {
				it.remove();
			}
		}
	}	
	
	/**
	 * Este metodo apaga o objeto Produto
	 * @throws DaoException 
	 */
	public void apagar(Produto produto) throws DaoException {
		apagar(produto.getId());
	}
	
	/**
	 * Este metodo salva o objeto Produto 
	 * @throws DaoException 
	 */
	public void salvar(Produto produto) throws DaoException {
		Iterator<Produto> it = ProdutoDAO.tabela.iterator();
		while (it.hasNext()) {
			Produto p = it.next();
			if (p.getId() == produto.getId()) {
				it.remove();
			}
		}
		ProdutoDAO.tabela.add(copy(produto));
	}
	
	/**
	 * Este metodo cria o objeto Produto e retorna o objeto criado com o novo id
	 * preenchido
	 * @throws DaoException 
	 */
	public void criar(Produto produto) throws DaoException {
		
		int novoIdProduto = getProximoValorSequence();
		produto.setId(novoIdProduto);
		ProdutoDAO.tabela.add(copy(produto));
	}
}
